
def print_timing(func):
    import time
    def wrapper(*args, **kwargs):
        t1 = time.time()
        res = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f s ~ %0.0f min and %0.1f sec' % (func.func_name, t2-t1, int(t2 - t1)/60, (t2-t1) % 60 )
        return res
    return wrapper

def print_start_finish(func):
    import time
    def wrapper(*args, **kwargs):
        import datetime
        now = datetime.datetime.now()
        print '************************************************'
        print "starting run at %s"%now.strftime("%Y-%m-%d %H:%M")
        print '************************************************'
        #f.flush()
        res = func(*args, **kwargs)
        now = datetime.datetime.now()
        print '************************************************'
        print "ending run at %s"%now.strftime("%Y-%m-%d %H:%M")
        print '************************************************'
        #f.flush()
        return res
    return wrapper

def trunc_cell_tables_csv_file(csvfilename, newcsvfilename, rownum):
    cf = open(csvfilename)
    ncf = open(newcsvfilename, 'w')
    i=0
    for line in cf:
        if i == rownum:
            break
        else:
            i = i+1
            ncf.write(line)
    ncf.close()
    cf.close()

def is_blankline(line):
    if line.isspace() or len(line)==0:
        return True
    else:
        return False

def file_exists(name, do_print=True):
    import os
    rv = os.path.exists(name) and os.path.getsize(name) > 0
    if rv and do_print:
        print 'file %s already exists'%(name,)
    return rv

def file_not_exist(name, do_print=True):
    import os
    rv = not os.path.exists(name) or os.path.getsize(name) == 0
    if rv and do_print:
        print 'file %s does not exist'%(name,)
    return rv

def get_conf():
    import configobj
    try:
        default = configobj.ConfigObj('default_conf', raise_errors=True)
    except configobj.ConfigObjError:
        print "ERROR FOR CONFIG FILE 'default_conf':"
        raise
    try:
        user = configobj.ConfigObj('user_conf', raise_errors=True)
    except configobj.ConfigObjError:
        print "ERROR FOR CONFIG FILE 'user_conf':"
        raise
    default.merge(user)
    return default

def randstr(n=5):
    import string
    from random import choice
    chars = string.ascii_lowercase + string.digits
    return ''.join([choice(chars) for i in xrange(n)])

def get_conf():
    import configobj, validate, sys
    try:
        config = configobj.ConfigObj('default_conf', configspec='conf.validate', raise_errors=True)
    except configobj.ConfigObjError:
        print "ERROR FOR CONFIG FILE 'default_conf':"
        raise
    try:
        user = configobj.ConfigObj('user_conf', configspec='conf.validate', raise_errors=True)
    except configobj.ConfigObjError:
        print "ERROR FOR CONFIG FILE 'user_conf':"
        raise
    config.merge(user)

    validator = validate.Validator()
    results = config.validate(validator, preserve_errors=True)
    if results != True:
        for entry in configobj.flatten_errors(config, results):
            # each entry is a tuple
            section_list, key, error = entry
            if key is not None:
                section_list.append(key)
            else:
                section_list.append('[missing section]')
            section_string = ', '.join(section_list)
            if error == False:
                error = 'Missing value or section.'
            print section_string, ' = ', error

        sys.exit(1)

    return config

def safe_mkdir(dirname):
    import os, sys
    if os.path.exists(dirname):
        if not os.path.isdir(dirname):
            sys.exit("error: path exists but is not a directory")
    else:
        os.makedirs(dirname)

def sqla_major_version():
    import sqlalchemy
    v = sqlalchemy.__version__
    return int(v.split('.')[1])

def pg_url():
    if sqla_major_version() >= 6:
        return 'postgresql+psycopg2'
    else:
        return 'postgres'

def text_autocommit(s):
    from sqlalchemy.sql import text
    if sqla_major_version() >= 6:
        return text(s).execution_options(autocommit=True)
    else:
        return text(s, autocommit=True)

def create_engine_wrapper(dbstring):
    from sqlalchemy import create_engine
    if sqla_major_version() >= 6:
        return create_engine(dbstring, use_native_unicode=False)
    else:
        return create_engine(dbstring)
